package com.myk.game.gobangchess.rooms.oldrooms;

import com.myk.game.gobangchess.Room;
import com.myk.game.gobangchess.constants.BoardStyleData;
import com.myk.game.gobangchess.constants.ColorCost;
import com.myk.game.gobangchess.constants.WinMode;
import com.myk.game.gobangchess.signs.GroundSign;

/**
 * 五赢棋
 */
public class FiveGoodRoom extends Room {

    protected int[] lastPoint;
    protected boolean overFlag; //是否两步都完成了

    private static final int PN = 8; //棋子混棋

    public FiveGoodRoom(String roomName) {
        super(roomName, "与三败棋落子规则一样，但是连五获胜。", "五赢棋",BoardStyleData.getGoBangStyle(13,13), true, true);
    }

    @Override
    public String getRuleText() {
        return "双方持相同的棋子，先手第一步落1子，之后双方轮流落2子，谁先连5谁获胜，落子位置与对手最后一颗棋子的距离不能超过3。";
    }

    @Override
    public void resetGrids() {
        super.resetGrids();
        lastPoint = null;
        overFlag = false;
    }

    @Override
    public String getGameInfo() {
        signList.clear();
        if (lastPoint != null) {
            signList.add(new GroundSign(getIndex(lastPoint[0], lastPoint[1]), ColorCost.TRANSPARENT, ColorCost.NEW_PUT_POINT, 1.0f, 0, 0));
            for (int i = 0; i < curGrids.length; i++) {
                for (int j = 0; j < curGrids[i].length; j++) {
                    if (curGrids[i][j] == 0 && !isOverDistance(i,j)) {
                        signList.add(new GroundSign(getIndex(i, j), ColorCost.NEW_PUT_POINT_LIGHT, ColorCost.TRANSPARENT, 1.0f, 0, 0));
                    }
                }
            }
        }
        return super.getGameInfo();
    }

    @Override
    public void doRule(int row, int col, int value) {
        if (curGrids[row][col] != 0) {
            return;
        }
        if (step > 0 && isOverDistance(row,col)){
            return;
        }
        if (step == 0){
            lastPoint = new int[]{row,col,PN};
            curGrids[row][col] = PN;
            overFlag = true;
            stepAdd();
            noticeChangeMove();
        }
        else {
            if (overFlag){
                curGrids[row][col] = PN;
                overFlag = false;
                int winState = checkFormation(PN, 5);
                if (winState > 0) {
                    stepAdd();
                    doWin(value);
                }
                else {
                    stepAdd();
                    noticeAllRefreshGameInfo();
                }
            }
            else {
                lastPoint = new int[]{row,col,PN};
                curGrids[row][col] = PN;
                overFlag = true;
                int winState = checkFormation(PN,  5);
                if (winState > 0) {
                    stepAdd();
                    doWin(value);
                }
                else {
                    stepAdd();
                    noticeChangeMove();
                }
            }
        }
    }

    private void doWin(int value) {
        if (value == 1){
            doOver(WinMode.BLACK_WIN,"黑方赢");
        }
        else {
            doOver(WinMode.WHITE_WIN,"白方赢");
        }
    }

    private boolean isOverDistance(int row, int col) {
        return Math.abs(row - lastPoint[0]) + Math.abs(col - lastPoint[1]) > 3;
    }

    //切换行动方
    protected void noticeChangeMove() {
        if (cur == 1) {
            noticeWhiteMove();
        }
        else if (cur == 2) {
            noticeBlackMove();
        }
    }

    private int checkFormation(int value, int winLength) {
        int rows = curGrids.length;
        int cols = curGrids[0].length;
        int formationCount = 0;

        // 水平方向
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols - winLength + 1; j++) {
                int length = 0;
                for (int k = j; k < j + winLength; k++) {
                    if (curGrids[i][k] == value) {
                        length++;
                    }
                    else {
                        break;
                    }
                }
                if (length >= winLength) {
                    formationCount += (length - winLength + 1);
                }
            }
        }

        // 垂直方向
        for (int i = 0; i < rows - winLength + 1; i++) {
            for (int j = 0; j < cols; j++) {
                int length = 0;
                for (int k = i; k < i + winLength; k++) {
                    if (curGrids[k][j] == value) {
                        length++;
                    }
                    else {
                        break;
                    }
                }
                if (length >= winLength) {
                    formationCount += (length - winLength + 1);
                }
            }
        }

        // 左上到右下方向
        for (int i = 0; i < rows - winLength + 1; i++) {
            for (int j = 0; j < cols - winLength + 1; j++) {
                int length = 0;
                for (int k = 0; k < winLength; k++) {
                    if (curGrids[i + k][j + k] == value) {
                        length++;
                    }
                    else {
                        break;
                    }
                }
                if (length >= winLength) {
                    formationCount += (length - winLength + 1);
                }
            }
        }

        // 右上到左下方向
        for (int i = 0; i < rows - winLength + 1; i++) {
            for (int j = winLength - 1; j < cols; j++) {
                int length = 0;
                for (int k = 0; k < winLength; k++) {
                    if (curGrids[i + k][j - k] == value) {
                        length++;
                    }
                    else {
                        break;
                    }
                }
                if (length >= winLength) {
                    formationCount += (length - winLength + 1);
                }
            }
        }

        return formationCount;
    }

    protected int getJudgeLength(int x, int y, int dx, int dy) {
        int value = curGrids[x][y];
        int length = 0;
        while (isInGrids(x, y)) {
            if (curGrids[x][y] != value) {
                return length;
            }
            length++;
            x += dx;
            y += dy;
        }
        return length;
    }

        // 判断位置在棋盘上
    protected boolean isInGrids(int row, int col) {
        return row >= 0 && row <= curGrids.length - 1 && col >= 0 && col <= curGrids[0].length - 1;
    }

}
